<?php
class mcz_Cache
{
    private static $caches;
    private $dir;
    public function __construct($dir = mcz_CACHE_DIR, $mkdir = false)
    {
		$slash = substr($dir,-1);
		if($slash != '/' and $slash !='\\')
		{
			$dir .= '/';
		}
        if($mkdir)
        {
            if(@!mkdir($dir, 0777, true))
            {
                throw new Exception(T('Could not create directory: ') . $dir);
            }
        }
        if(!is_writable($dir))
        {
            throw new Exception(T('Directory is not writable: ') . $dir);
        }
        $this->dir = $dir;
    }
    
    
    public function fetch($key)
    {
        $paths = $this->mkPaths($key);
		if(!is_file($paths['meta']))
		{
			return false;
		}
		$metas = unserialize(file_get_contents($paths['meta']));
		if($metas['expires'] < time() and $metas['expires'] != 0)
		{
			unlink($paths['meta']);
			unlink($paths['cache']);
			return false;
		}
		return unserialize(file_get_contents($paths['cache']));
    }
    
    public function store($key, $value, $ttl = 0)
    {
        $paths = $this->mkPaths($key);
		if($ttl == 0)
		{
			$expires = 0;
		}
		else
		{
			$expires = time() + (int)$ttl;
		}
		file_put_contents($paths['cache'], serialize($value));
		file_put_contents($paths['meta'], serialize(array(
			'key'     => $key,
			'expires' => $expires,
			'file'    => basename($paths['cache'])
		)));
		return $value;
    }
    
    public function delete($key)
    {
		$paths = $this->mkPaths($key);
		if(unlink($paths['meta']) and unlink($paths['cache']))
		{
			return true;
		}
		return false; 
    }

	public function cacheInfos()
	{
		$metaFiles = glob($this->dir . '*.meta');
		$metas = array();
		foreach($metaFiles as $metaFile)
		{
			$metas[] = unserialize(file_get_contents($metaFile));
		}
		return $metas;
	}

	public function clear($removeDirectory = true)
	{
		$infos = $this->cacheInfos();
		foreach($infos as $info)
		{
			$this->delete($info['key']);
		}
		if($removeDirectory)
		{
			return rmdir($this->dir);
		}
		return true;
	}
    
    private function mkPaths($key)
    {
		$hash = md5($key);
		return array(
			'meta'  => $this->dir . $hash . '.meta',
			'cache' => $this->dir . $hash . '.cache'
		);
    }
    
    public static function _($cacheId = 'default', $dir = mcz_CACHE_DIR,
                             $mkdir = false)
    {
        if(!isset(self::$caches[$cacheId]))
        {
            self::$caches[$cacheId] = new mcz_Cache($dir, $mkdir);
        }
        return self::$caches[$cacheId];
    }
}